﻿using SX.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SX.Data
{
    public class WhereBuilder
    {
        StringBuilder builder = new StringBuilder();

        public static WhereBuilder CreateBuilder(ConditionBase condition)
        {
            WhereBuilder instance = new WhereBuilder();
            instance.LoadCondition(condition);
            return instance;
        }
        public static WhereBuilder CreateBuilder4Mongo(ConditionBase condition)
        {
            WhereBuilder4Mongo instance = new WhereBuilder4Mongo();
            instance.LoadCondition(condition);
            return instance;
        }
        /// <summary>
        /// 加载条件
        /// </summary>
        /// <param name="condition">The condition.</param>
        public virtual WhereBuilder LoadCondition(ConditionBase condition)
        {
            foreach (string key in condition.ConditionDic.Keys)
            {
                string value = condition[key];
                value = value.Replace("'", "''"); // 防止注入 
                if (key.StartsWith("r_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 2;
                    string op = "=";
                    if (key.EndsWith("_fr"))
                    {
                        op = ">=";
                        length = key.Length - 5;

                    }
                    else if (key.EndsWith("_to"))
                    {
                        op = "<=";
                        value = value + " 23:59:59";
                        length = key.Length - 5;
                    }
                    string field = key.Substring(2, length);
                    if (value.IndexOf(",") > 0)
                    {
                        op = "in";
                        value = value.Replace(",", "','");
                    }
                    this.And(field.Replace("-", "."), op, value);
                }
                else if (key.StartsWith("l_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 2;
                    string field = key.Substring(2, length);
                    string op = "like";
                    this.And(field.Replace("-", "."), op, "%" + value + "%");
                }

                else if (key.StartsWith("i_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 2;
                    string field = key.Substring(2, length);
                    string op = "in";

                    value = value.Replace(",", "','");
                    this.And(field.Replace("-", "."), op, value);
                }
                else if (key.StartsWith("ni_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 3;
                    string field = key.Substring(3, length);
                    string op = "not in";

                    value = value.Replace(",", "','");
                    this.And(field.Replace("-", "."), op, value);
                }
                // 位运算 
                else if (key.StartsWith("b_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 2;
                    string field = key.Substring(2, length);
                    var valueList = value.Split(',').Select(d => CommonHelper.ToInt(d)).ToList();
                    int bitV = 0;
                    foreach (var i in valueList)
                    {
                        bitV = i | bitV;
                    }
                    this.AddFormat(" {0} & {1} ={1}", field.Replace("-", "."), bitV);
                }
                // 位运算 in
                else if (key.StartsWith("bi_") && !string.IsNullOrEmpty(value))
                {
                    int length = key.Length - 3;
                    string field = key.Substring(3, length);
                    var valueList = value.Split(',').Select(d => CommonHelper.ToInt(d)).ToList();
                    int bitV = 0;
                    foreach (var i in valueList)
                    {
                        bitV = i | bitV;
                    }
                    this.AddFormat(" {0} & {1} > 0 ", field.Replace("-", "."), bitV);
                }
            }

            return this;
        }
        public virtual WhereBuilder AddFormat(string format, params object[] args)
        {
            return And(string.Format(format, args));
        }
        public virtual WhereBuilder And(string where)
        {
            if (!string.IsNullOrEmpty(builder.ToString()))
            {
                builder.Append(" and ");
            }
            builder.Append(where);
            return this;
        }
        public virtual WhereBuilder And(string field, string op, string value)
        {

            switch (op)
            {
                case "in":
                    And(string.Format(" {0} {1} ('{2}')", field, op, value));
                    break;
                case "not in":
                    And(string.Format(" {0} {1} ('{2}')", field, op, value));
                    break;
                default:
                    And(string.Format(" {0} {1} '{2}'", field, op, value));
                    break;
            }
            return this;
        }
        public override string ToString()
        {
            return builder.ToString();
        }
    }
}
